package alpaca.network;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;

import alpaca.util.SystemMessage;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;

public class KryoClientConnection extends Listener implements IClientConnection {

	private PropertyChangeSupport pcs;
	private Server server;

	
	public KryoClientConnection(){
		pcs = new PropertyChangeSupport(this);
		server = new Server(98304, 10240);
		
		/**
		 * Uses NetworkRegistration in shared temporarily.
		 */
		NetworkRegistration.register(server);
		server.addListener(this);
	}
	
	@Override
	public void start(int port) throws IOException{

		server.start();
		server.bind(port);
	}
	
	@Override
	public void stop(){
		server.stop();
	}

	@Override
	public void send(int connID, NetworkMessage nm) {
		System.out.println("Server sent: " + nm.getObject().getClass());
		server.sendToTCP(connID, nm);
	}
	
	@Override
	public void closeConnection(int connID){
		Connection[] conns = server.getConnections();
		for (int i = 0; i < conns.length; i++) {
			if(conns[i].getID() == connID){
				conns[i].close();
			}
		}
	}
	
	/**
	 * Override from {@link Listener}
	 */
	@Override
	public void received(Connection conn, Object o) {
		if (o instanceof NetworkMessage){
			NetworkMessage nm = (NetworkMessage)o;
			nm.setFromConnectionId(conn.getID());
			pcs.firePropertyChange("received", null, o);
			System.out.println("Server received: " + ((NetworkMessage) o).getObject().getClass());
		}
	}
	
	/**
	 * Override from {@link Listener}
	 */
	@Override
	public void connected(Connection conn){	
		pcs.firePropertyChange("joined", null, new SystemMessage(server.getConnections().length, SystemMessage.Type.CONN_AMOUNT));
	}
	
	/**
	 * Override from {@link Listener}
	 */
	@Override
	public void disconnected(Connection conn){
		pcs.firePropertyChange("left", null, new SystemMessage(server.getConnections().length, SystemMessage.Type.CONN_AMOUNT));
		pcs.firePropertyChange("disconnect", null, new SystemMessage(conn.getID(), SystemMessage.Type.DISCONNECT));
	}
	
	@Override
	public void addPropertyChangeListener(PropertyChangeListener pcl) {
		pcs.addPropertyChangeListener(pcl);
	}
	
	@Override
	public void removePropertyChangeListener(PropertyChangeListener pcl) {
		pcs.removePropertyChangeListener(pcl);
	}

}
